//
//  UITextView+Extension.swift
//  SK_BasePrivateProject
//
//  Created by mac on 2018/7/20.
//  Copyright © 2018年 Regina. All rights reserved.
//

import Foundation
import UIKit

private struct AssociatedKeys {
    static var placeholder = "placeholder"
    static var maxLength = "maxLength"
    static var autoHeight = "autoHeight"
    static var textHeight = "textHeight"
}

extension UITextView  {
    static func awake() {
        swizzleMethod
    }

    fileprivate var textHeight: Int {
        get {
            guard let height = objc_getAssociatedObject(self, &AssociatedKeys.textHeight) as? Int else {
                return 0
            }
            return height
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.textHeight, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }

    }
    
    public typealias SKAutoHightBlock = ((CGFloat) -> Void)

    private class BlockContainer: NSObject, NSCopying {
        func copy(with zone: NSZone? = nil) -> Any {
            return self
        }
        var block: SKAutoHightBlock?
    }
    
    public var autoHightBlock:SKAutoHightBlock? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.autoHeight) as? SKAutoHightBlock
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.autoHeight,newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }

    public var placeholder: String {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.placeholder) as! String
        }
        set {
            self.setPlaceholder(newValue)
            objc_setAssociatedObject(self, &AssociatedKeys.placeholder, newValue, .OBJC_ASSOCIATION_COPY)
        }
    }

    public var maxLength: Int {
        get {
            guard let maxLength = objc_getAssociatedObject(self, &AssociatedKeys.maxLength) as? Int else {
                return 0
            }
            return maxLength
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.maxLength, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }
    }

    public convenience init(autoHeight: @escaping SKAutoHightBlock) {
        self.init(frame: .zero)
//        let blockContainer: BlockContainer = BlockContainer()
//        blockContainer.block = autoHeight
        self.autoHightBlock = autoHeight
    }

    private static let swizzleMethod: Void = {
        let originalSelector = #selector(UITextView.init(frame:))
        let swizzleSelector = #selector(UITextView.swizzle_init(frame:))
        swizzlingForClass(UITextView.self, originalSelector: originalSelector, swizzledSelector: swizzleSelector)
    }()

    @objc func swizzle_init(frame: CGRect) -> UITextView {
        let textView = self.swizzle_init(frame: frame)
        NotificationCenter.default.addObserver(self, selector: #selector(textViewDidChange), name: .UITextViewTextDidChange, object: nil)
        return textView
    }

    private static func swizzlingForClass(_ forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
        let originalMethod = class_getInstanceMethod(forClass, originalSelector)
        let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
        guard (originalMethod != nil && swizzledMethod != nil) else {
            return
        }
        if class_addMethod(forClass, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!)) {
            class_replaceMethod(forClass, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
        } else {
            method_exchangeImplementations(originalMethod!, swizzledMethod!)
        }
    }

    @objc func textViewDidChange() {

        if self.autoHightBlock != nil {
            
            let size = self.sizeThatFits(CGSize(width: self.bounds.size.width, height:.infinity))
            self.autoHightBlock!(size.height)

        }

        if self.maxLength <= 0 {
            return
        }
        
        if let selectRange = self.markedTextRange {
            let position =  self.position(from: (selectRange.start), offset: 0)
            if (position != nil) {
                return
            }
        }
        
        let textContent = self.text
        let textNum = textContent?.count
        
        
        if textNum! > self.maxLength {
            let str = textContent?.subStringToIndex(self.maxLength)
            self.text = str
        }
        

//        let inputMethodType: String = UIApplication.shared.textInputMode!.primaryLanguage!
//        if inputMethodType == "zh-Hans" {
//            if let selectedRange = self.markedTextRange {
//                if self.position(from: selectedRange.start, offset: 0) == nil {
//                    self.text = self.textViewCurrentText()
//                    return
//                }
//            }
//        }else {
//            self.text = self.textViewCurrentText()
//        }
    }

    func textViewCurrentText() -> String{
        return self.text.count > self.maxLength ? self.text.subStringToIndex(self.maxLength)! : self.text
    }

    fileprivate func setPlaceholder(_ placeholdStr: String , _ placeholdColor: UIColor = REHexRGB(0x888888)) {

        let placeHolderLabel: UILabel = UILabel()
        placeHolderLabel.text = placeholdStr
        placeHolderLabel.isEnabled = false
        placeHolderLabel.textColor = placeholdColor
        placeHolderLabel.numberOfLines = 0
        placeHolderLabel.font = self.font
        placeHolderLabel.sizeToFit()
        self.addSubview(placeHolderLabel)
        
        self.setValue(placeHolderLabel, forKey: "_placeholderLabel")

    }
    
    ///处理文字长度
    func trimmingNeedlessCharacters(_ length: Int) {
        
        if self.markedTextRange != nil { return }
        if self.text == nil { return }
        
        //当前光标的位置（后面会对其做修改）
        let cursorPostion =  self.offset(from: self.endOfDocument, to: self.selectedTextRange!.end)
        
        var text = self.text!
        //如果长度超过限制则直接截断
        text = text.subStringToIndex(length) ?? ""
        self.text = text
        //让光标停留在正确位置
        let targetPostion =  self.position(from: self.endOfDocument, offset: cursorPostion)!
        self.selectedTextRange =  self.textRange(from: targetPostion, to: targetPostion)
        
    }
    
    ///处理文字长度
    func trimmingNeedlessCharacters(_ length: Int, byReplacingMatches pattern: String) {
        
        if self.markedTextRange != nil { return }
        if self.text == nil { return }
        
        //当前光标的位置（后面会对其做修改）
        let cursorPostion =  self.offset(from: self.endOfDocument, to: self.selectedTextRange!.end)
        
        var text = self.text!
        text = text.replaceWithRegular(pattern: pattern, with: "")
        
        //如果长度超过限制则直接截断
        text = text.subStringToIndex(length) ?? ""
        self.text = text
        //让光标停留在正确位置
        let targetPostion =  self.position(from: self.endOfDocument, offset: cursorPostion)!
        self.selectedTextRange =  self.textRange(from: targetPostion, to: targetPostion)
    }
}
